<template>
  <view
    class="region-picker custom-comp"
    :class="[getDisabled && 'is-disabled', getBorder && 'is-border']"
  >
    <picker
      mode="multiSelector"
      @change="onChange"
      @columnchange="onColumnchange"
      range-key="extName"
      style="flex: 1"
      :disabled="getDisabled"
      :range="range"
      :value="pickerIndexValue"
    >
      <PickerValue
        v-if="!getDisabled || getShowValue"
        style="height: 100%"
        :value-text="getShowValue"
        :placeholder="getPlaceholder"
        :disabled="getDisabled"
        :icon="getShowValue && !getDisabled ? '\ue724' : '\ue611'"
        :icon-style="
          getShowValue && !getDisabled
            ? {
                color: 'rgb(192, 196, 204)',
                fontSize: '40rpx',
              }
            : {
                fontSize: '30rpx',
              }
        "
        @icon-click="handleClear"
      />
    </picker>
  </view>
</template>

<script setup lang="ts">
  import { type IAreaDataResultItem } from '@/api/indexTypes';
  import { isArray, isBoolean } from '@/utils/is';
  import { propTypes } from '@/utils/propTypes';
  import { computed, ref, watch, unref, type PropType } from 'vue';
  import { useFormItem } from '../hooks/useContext';
  import PickerValue from './PickerValue.vue';
  import { getCityData } from '../utils/getCityData';
  import { cloneDeep } from 'lodash-es';

  const props = defineProps({
    modelValue: {
      type: Array as PropType<number[]>,
    },
    clearIcon: propTypes.bool.def(false),
    // 显示街道
    showStreet: propTypes.bool.def(false),
    /** 是否显示区县 */
    showArea: propTypes.bool.def(true),
    border: {
      type: Boolean,
      default: undefined,
    },
    placeholder: propTypes.string.def(''),
    disabled: propTypes.bool.def(false),
  });

  const emits = defineEmits(['update:modelValue']);

  const range = ref<Array<IAreaDataResultItem[]>>([]);
  const pickerIndexValue = ref<number[]>([0, 0, 0]);

  const { getProps, setFormModel, formProps } = useFormItem({});

  const getBorder = computed(() => (isBoolean(props.border) ? props.border : !formProps?.border));

  const showVal = ref<IAreaDataResultItem[]>([]);

  const getShowValue = computed(() => {
    return showVal.value.map((v) => v.extName).join('');
  });

  const getPlaceholder = computed(() => {
    let text = props.showArea ? '请选择省市区' : '请选择省市';
    return getProps.value.placeholder || props.placeholder || text;
  });

  const getDisabled = computed(() => getProps.value.disabled || props.disabled);

  const isInit = ref(false);
  watch(
    [() => getProps.value.modelValue, () => props.modelValue],
    ([v1, v2]) => {
      if (unref(isChange)) {
        isChange.value = false;
        return;
      }
      const val = v1 || v2;
      if (isInit.value && !val?.length) return;

      showVal.value = [];
      isInit.value = true;
      __init();
    },
    {
      immediate: true,
      deep: true,
    },
  );

  const isChange = ref(false);
  const onChange = (e: any) => {
    isChange.value = true;
    const indexs = (e.detail?.value as number[]) || [];
    showVal.value = [];
    indexs.forEach((v, i) => showVal.value.push(range.value[i][v]));

    setFormModel(showVal.value.map((v) => v.id).join(','));
    emits(
      'update:modelValue',
      showVal.value.map((v) => v.id),
    );
  };

  async function onColumnchange(e: { detail: { column: number; value: number } }) {
    const { column, value } = e.detail;
    let pIndex = value;
    let index = column;
    while (index < unref(pickerIndexValue).length) {
      const pid = range.value[index][pIndex].id;

      pickerIndexValue.value[index] = pIndex;
      index++;
      index < unref(pickerIndexValue).length && (await getData(pid, index));
      pIndex = 0;
    }
  }

  async function getData(pid: number = 0, type: number = 0) {
    const res = await getCityData(pid);
    range.value[type] = res;
    return res;
  }

  function getIndex(data: IAreaDataResultItem[], id?: number) {
    let index = data.findIndex((v) => v.id == id);
    return index === -1 ? 0 : index;
  }

  async function __init() {
    let valArr = (getProps.value.modelValue as string) || props.modelValue || [];
    let vals = isArray(valArr) ? valArr : valArr.split(',');

    showVal.value = [];

    /** 修改默认值为广东省深圳市南山区 南头街道 */
    if (vals.length < 3 && props.showArea) {
      vals = ['44', '4403', '440305'];
      if (props.showStreet) vals.push('440305001');
    }

    let provinceId = Number(vals[0]),
      cityId = Number(vals[1]),
      districtId = Number(vals[2]),
      townId = Number(vals[3]);

    const valIds: number[] = [];

    const province = await getData();
    const pIndex = getIndex(province, provinceId);
    valIds[0] = provinceId || province[0].id;

    const city = await getData(valIds[0], 1);
    const cIndex = getIndex(city, cityId);
    valIds[1] = cityId || city[0].id;

    if (valArr.length) {
      showVal.value[0] = cloneDeep(province[pIndex]);
      showVal.value[1] = cloneDeep(city[cIndex]);
    }

    pickerIndexValue.value = [pIndex, cIndex];

    if (props.showArea) {
      const district = await getData(valIds[1], 2);
      const dIndex = getIndex(district, districtId);
      valIds[2] = districtId || district[0].id;
      valArr[2] && (showVal.value[2] = cloneDeep(district[dIndex]));
      pickerIndexValue.value[2] = dIndex;
    }

    if (props.showStreet) {
      const town = await getData(valIds[2], 3);
      const tIndex = getIndex(town, townId);
      valIds[3] = townId || town[0].id;
      valArr[3] && (showVal.value[3] = cloneDeep(town[tIndex]));
      pickerIndexValue.value[3] = tIndex;
    }
  }

  function handleClear() {
    if (getShowValue.value && !getDisabled.value) {
      isChange.value = true;
      showVal.value = [];
      setFormModel([]);
      emits('update:modelValue', []);
    }
  }
</script>

<style lang="scss" scoped>
  @import '../styles/form.scss';
</style>
